using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ctsu.Admin.Forms;
using ctsu.BaseForms;
using ctsu.Data;
using ctsu.Security;
using ctsu.Shared;
using Microsoft.Practices.EnterpriseLibrary.Data;

using Syncfusion.Windows.Forms.Tools;
namespace ctsu.Admin.BusLogic
{
	public class BLFormQA2Impl : BLFormBaseImpl
	{
		enum SearchTypes { Standard, OutpatientVisits, Admissions, Patient, Protocol, Investigator };
		private SearchTypes _searchType = SearchTypes.Standard;

		const int MaxGroupColumns = 4;
		const int FirstGroupColumnX = 10;
		const int GroupColumnWidth = 250;
		private DataSet _dsFieldGroups;
		private DataTable _dtCheckData;
		private DataTable _dtOtherData;
		private ArrayList _alrcCbItems;
		private Hashtable _htrcCbItems;
		private ArrayList _alrcTbItems;
		private Hashtable _htrcTbItems;
		private Hashtable _htNewOtherItems;

		#region control references
		private Syncfusion.Windows.Forms.Tools.DateTimePickerAdv _visitDate;
		private Syncfusion.Windows.Forms.Tools.DateTimePickerAdv _discoveryDate;
		private Syncfusion.Windows.Forms.Tools.DateTimePickerAdv _dtpIncidentTime;
		private TextBox _incidentTime;
		private ComboBox _visitType;
		private TextBox _visitID;
		private TextBox _patient;
		private TextBox _mrn;
		private TextBox _patientName;
		private TextBox _protocol;
		//private TextBox _spid;
		private TextBox _protocolNumber;
		private TextBox _investigator;
		private TextBox _timeIn;
		private Button _btnVisit;
		private Button _btnPrint;
		private TabControlAdv _tabCtl;
		private RadioButton _rdoPhlebotomy;
		private RadioButton _rdoNone;
		private RadioButton _rdoIV;
		private Syncfusion.Windows.Forms.Tools.NumericUpDownExt _sticks;
		private Syncfusion.Windows.Forms.Tools.NumericUpDownExt _painScore;
		private Syncfusion.Windows.Forms.Tools.NumericUpDownExt _recovery;
		private CheckBox _piuNothing;
		private CheckBox _piuPharmacologic;
		private CheckBox _piuBehavioral;
		private CheckBox _piuOther;
		private CheckBox _piuNotDocumented;
		private TextBox _otherTechnique;
		private TextBox _ivAudit;
		private Panel _pnlIV;
		private ComboBox _painScale;
		private ComboBox _sampleCollection;

		#endregion control references

		#region initialize
		public BLFormQA2Impl(FormMain formMain, FormBase form, FormInfoBase formInfo, DataTable tableSchema, Permission formSecurity, Hashtable configData)
			: base(formMain, form, formInfo, tableSchema, formSecurity, configData)
		{
		}

		protected override void _vcManager_OnAfterHookEvents()
		{
			_visitDate = (DateTimePickerAdv)Forms.Utils.GetControlByName("VisitDate", this._form.Controls);
			_discoveryDate = (DateTimePickerAdv)Forms.Utils.GetControlByName("DiscoveryDate", this._form.Controls);
			_dtpIncidentTime = (DateTimePickerAdv)Forms.Utils.GetControlByName("dtpIncidentTime", this._form.Controls);
			_incidentTime = (TextBox)Forms.Utils.GetControlByName("IncidentTime", this._form.Controls);
			_timeIn = (TextBox)Forms.Utils.GetControlByName("TimeIn", this._form.Controls);
			_visitType = (ComboBox)Forms.Utils.GetControlByName("VisitType", this._form.Controls);
			_visitID = (TextBox)Forms.Utils.GetControlByName("VisitID", this._form.Controls);
			_patient = (TextBox)Forms.Utils.GetControlByName("Patient", this._form.Controls);
			_mrn = (TextBox)Forms.Utils.GetControlByName("MRN", this._form.Controls);
			_patientName = (TextBox)Forms.Utils.GetControlByName("PatientName", this._form.Controls);
			_protocol = (TextBox)Forms.Utils.GetControlByName("Protocol", this._form.Controls);
			//_spid = (TextBox)Forms.Utils.GetControlByName("SPID", this._form.Controls);
			_protocolNumber = (TextBox)Forms.Utils.GetControlByName("ProtocolNumber", this._form.Controls);
			_investigator = (TextBox)Forms.Utils.GetControlByName("Investigator", this._form.Controls);
			_btnVisit = (Button)Forms.Utils.GetControlByName("btnVisit", this._form.Controls);
			_btnPrint = (Button)Forms.Utils.GetControlByName("btnPrint", this._form.Controls);
			_rdoPhlebotomy = (RadioButton)Forms.Utils.GetControlByName("rdoPhlebotomy", this._form.Controls);
			_rdoNone = (RadioButton)Forms.Utils.GetControlByName("rdoNone", this._form.Controls);
			_rdoIV = (RadioButton)Forms.Utils.GetControlByName("rdoIV", this._form.Controls);
			_sticks = (NumericUpDownExt)Forms.Utils.GetControlByName("Sticks", this._form.Controls);
			_painScore = (NumericUpDownExt)Forms.Utils.GetControlByName("PainScore", this._form.Controls);
			_recovery = (NumericUpDownExt)Forms.Utils.GetControlByName("Recovery", this._form.Controls);
			_piuNotDocumented = (CheckBox)Forms.Utils.GetControlByName("PiuNotDocumented", this._form.Controls);
			_piuNothing = (CheckBox)Forms.Utils.GetControlByName("PiuNothing", this._form.Controls);
			_piuPharmacologic = (CheckBox)Forms.Utils.GetControlByName("PiuPharmacologic", this._form.Controls);
			_piuBehavioral = (CheckBox)Forms.Utils.GetControlByName("PiuBehavioral", this._form.Controls);
			_piuOther = (CheckBox)Forms.Utils.GetControlByName("PiuOther", this._form.Controls);
			_otherTechnique = (TextBox)Forms.Utils.GetControlByName("OtherTechnique", this._form.Controls);
			_ivAudit = (TextBox)Forms.Utils.GetControlByName("IvAudit", this._form.Controls);
			_painScale = (ComboBox)Forms.Utils.GetControlByName("PainScale", this._form.Controls);
			_sampleCollection = (ComboBox)Forms.Utils.GetControlByName("SampleCollection", this._form.Controls);
			_pnlIV = (Panel)Forms.Utils.GetControlByName("pnlIV", this._form.Controls);
			_rdoPhlebotomy.CheckedChanged += new EventHandler(_rdoIvAudit_CheckedChanged);
			_rdoNone.CheckedChanged += new EventHandler(_rdoIvAudit_CheckedChanged);
			_rdoIV.CheckedChanged += new EventHandler(_rdoIvAudit_CheckedChanged);
			_dtpIncidentTime.ValueChanged += new EventHandler(_dtpIncidentTime_ValueChanged);
			_piuOther.CheckedChanged += new EventHandler(_piuOther_CheckedChanged);
			//_pnlIV.EnabledChanged += new EventHandler(_pnlIV_EnabledChanged);

			if (LoginForm.ApplicationSecurity.ApplicationUser.LastName != "Rezuke")
				this._form.btnRemove.Visible = false;
		}

		void _piuOther_CheckedChanged(object sender, EventArgs e)
		{
			if (_piuOther.Checked)
				_otherTechnique.Enabled = true;
			else
			{
				_otherTechnique.Text = "";
				_otherTechnique.Enabled = false;
			}
		}

		void SetIvControlsEnabled(bool enable)
		{
			foreach (Control ctl in _pnlIV.Controls)
				ctl.Enabled = enable;
			if (enable == false)
				ClearIvStickControls();
			else
			{
				if (!_piuOther.Checked)
					_otherTechnique.Enabled = false;
			}
		}

		void _dtpIncidentTime_ValueChanged(object sender, EventArgs e)
		{
			if (_dtpIncidentTime.IsNullDate)
				_incidentTime.Text = "00:00:00";
			else
				_incidentTime.Text = _dtpIncidentTime.Value.ToString("HH:mm:ss");
		}

		void _rdoIvAudit_CheckedChanged(object sender, EventArgs e)
		{
			Control ctl = (Control)sender;
			if (ctl.Name == "rdoPhlebotomy")
			{
				_ivAudit.Text = "2";
				SetIvControlsEnabled(true);
			}
			else if (ctl.Name == "rdoIV")
			{
				_ivAudit.Text = "1";
				SetIvControlsEnabled(true);
			}
			else
			{
				_ivAudit.Text = "0";
				SetIvControlsEnabled(false);
			}
		}

		public override bool Initialize()
		{
			if (!InitializeDSFieldGroups())
				return false;
			CreateGroupPanels();
			InitializeCheckBoxes();
			InitializeGroupColumns();  //according to MaxGroupColumns
			AdjustSize();
			return base.Initialize();
		}

		private void InitializeGroupColumns()
		{
			//groups table
			DataTable dt = _dsFieldGroups.Tables[1];

			TabControlAdv tabCtl = (TabControlAdv)Forms.Utils.GetControlByName("tabCtl", this._form.Controls);
			TabPageAdv tab = this._tabCtl.TabPages[2];

			Point pNext = new Point(0, 0);

			for (int i = 0; i < dt.Rows.Count; i++)
			{
				if (i > (MaxGroupColumns - 1))
				{
					pNext = GetShortestPanelLocation(tab);
					DataRow dr = dt.Rows[i];

					string pnlName = "pnlGroup" + dr["ID"].ToString();
					Panel pnl = (Panel)Forms.Utils.GetControlByName(pnlName, tab.Controls);
					pnl.Location = pNext;
					pnl.BringToFront();
				}
			}
		}


		private Point GetShortestPanelLocation(TabPageAdv tab)
		{
			int shortestY = 10000;
			int x = 0;
			int y = 0;

			int maxX = (GroupColumnWidth * MaxGroupColumns);
			int totColHeight = 0;
			Hashtable ht = new Hashtable(MaxGroupColumns);
			//first combine any groups that appear in the same column
			foreach (Control ctl in tab.Controls)
			{
				if (ctl.Name.StartsWith("pnl"))
				{
					//ignore any columns greater than max columns
					if (ctl.Left > maxX)
						continue;
					if (ht.Contains(ctl.Left))
					{
						totColHeight = ctl.Height + (int)ht[ctl.Left];
						ht[ctl.Left] = totColHeight;
					}
					else
					{
						totColHeight = ctl.Height;
						ht.Add(ctl.Left, totColHeight);
					}
				}
			}

			//get the shortest column            

			foreach (DictionaryEntry de in ht)
			{
				y = (int)de.Value;
				if (y < shortestY)
				{
					shortestY = y;
					x = (int)de.Key;
				}
			}

			return new Point(x, shortestY - 1);
		}

		private void AdjustSize()
		{
			//get the panel with extends most to the bottom of the tab
			TabPageAdv tab = (TabPageAdv)Forms.Utils.GetControlByName("tab2", this._form.Controls); ;
			int longest = 0;
			int height = 0;
			foreach (Control ctl in tab.Controls)
			{
				if (ctl.Name.StartsWith("pnlGroup"))
				{
					height = ctl.Height + ctl.Top;
					if (longest < height)
						longest = height;
				}
			}
			this._form.pnl2.Height = longest + 100;
			//this._tabCtl.Height = this._form.pnl2.Height - 12;
		}

		private void InitializeCheckBoxes()
		{
			this._alrcCbItems = new ArrayList();
			this._htrcCbItems = new Hashtable();
			this._alrcTbItems = new ArrayList();
			this._htrcTbItems = new Hashtable();

			int fieldID = 0;
			string fieldName = "";
			int groupID = 0;
			string groupName;
			int subGroupID = 0;
			string subGroupName;

			DataTable dt = _dsFieldGroups.Tables[0];

			int currentGroup = 0;
			int currentSubGroup = 0;
			int currentY = 0;
			Panel pnlGroup = null;
			CheckBox cb = null;
			foreach (DataRow dr in dt.Rows)
			{
				fieldID = (int)dr["ID"];
				fieldName = dr["FieldName"].ToString();
				groupID = (int)dr["GroupID"];
				groupName = dr["GroupName"].ToString();
				subGroupID = (int)dr["SubGroupID"];
				subGroupName = dr["SubGroupName"].ToString();

				if (groupID != currentGroup)
				{
					//adjust previous pnl height
					if (pnlGroup != null)
						pnlGroup.Height = currentY;
					string pnlName = "pnlGroup" + groupID;
					pnlGroup = (Panel)Forms.Utils.GetControlByName(pnlName, this._form.Controls);
					currentGroup = groupID;
					currentY = 15;
				}
				if (subGroupID != currentSubGroup)
				{
					currentSubGroup = subGroupID;
					if (subGroupName.Length > 0)
					{
						//create lable and add to group panel
						Label lbl = new Label();
						pnlGroup.Controls.Add(lbl);
						lbl.Width = pnlGroup.Width;
						lbl.Height = 16;
						lbl.Text = subGroupName;
						//lbl.TextAlign = ContentAlignment.TopCenter;
						Font font = new Font(lbl.Font, (FontStyle.Bold));
						lbl.Font = font;
						lbl.Visible = true;
						lbl.Location = new Point(0, currentY);
						currentY += 20;
						pnlGroup.Height += lbl.Height + 5;
					}
				}

				cb = CreateCheckBox(fieldID, fieldName);

				RowContextCB rc = new RowContextCB();
				rc._drField = dr;
				rc._control = cb;
				rc._drData = null;
				cb.Tag = rc;

				this._alrcCbItems.Add(rc);
				this._htrcCbItems.Add(fieldID, rc);

				pnlGroup.Controls.Add(cb);
				cb.Location = new Point(8, currentY);
				if (fieldName == "Other")
				{
					cb.Width = 100;
					TextBox tb = new TextBox();
					tb.Name = "t" + fieldID.ToString();
					tb.Width = 170;
					pnlGroup.Controls.Add(tb);
					tb.Location = new Point(65, currentY + 5);
					tb.Visible = true;
					tb.BringToFront();
					tb.TextChanged += new EventHandler(this.Central_TextChanged);
					tb.Validating += new CancelEventHandler(tb_Validating);

					RowContextTB rct = new RowContextTB();
					rct._control = tb;
					rct._fieldID = fieldID;
					tb.Tag = rct;

					this._alrcTbItems.Add(rct);
					this._htrcTbItems.Add(fieldID, rct);
				}
				currentY += cb.Height;
			}
			//adjust last panel
			pnlGroup.Height = currentY;
		}

		private CheckBox CreateCheckBox(int fieldID, string fieldName)
		{
			CheckBox cb = new CheckBox();
			cb.Name = "f" + fieldID.ToString();
			cb.Text = fieldName;
			Size sz = new Size(240, 38);
			cb.Size = sz;
			cb.Visible = true;
			cb.CheckedChanged += new EventHandler(this.Central_CheckedChanged);
			cb.Validating += new CancelEventHandler(checkBox_Validating);
			return cb;
		}

		private void checkBox_Validating(object sender, CancelEventArgs e)
		{
			CheckBox cb = (CheckBox)sender;
			RowContextCB rc = (RowContextCB)cb.Tag;

			rc._drData["Data"] = cb.Checked;
		}

		void tb_Validating(object sender, CancelEventArgs e)
		{
			TextBox tb = (TextBox)sender;
			RowContextTB rc = (RowContextTB)tb.Tag;

			rc._drData["Text"] = tb.Text;
		}

		private void CreateGroupPanels()
		{
			DataTable dt = _dsFieldGroups.Tables[1];

			Panel pnl = null;
			Label lbl = null;
			int groupCount = 0;
			int pnlX = 10;
			int pnlY = 0;
			_tabCtl = (TabControlAdv)Forms.Utils.GetControlByName("tabCtl", this._form.Controls);
			TabPageAdv tab = this._tabCtl.TabPages[2];

			foreach (DataRow dr in dt.Rows)
			{
				pnl = new Panel();
				tab.Controls.Add(pnl);
				pnl.Location = new Point(pnlX, pnlY);
				pnl.BorderStyle = BorderStyle.FixedSingle;

				pnl.Name = "pnlGroup" + dr["ID"].ToString();
				pnl.Size = new Size(250, 20);
				pnl.Visible = true;

				lbl = new Label();
				pnl.Controls.Add(lbl);
				lbl.Width = pnl.Width;
				lbl.Height = 16;
				lbl.Text = dr["Name"].ToString();
				lbl.TextAlign = ContentAlignment.TopCenter;
				Font font = new Font(lbl.Font, (FontStyle.Bold | FontStyle.Underline));
				lbl.Font = font;
				lbl.Visible = true;
				++groupCount;
				pnlX = (250 * groupCount) - groupCount + 10;
			}
		}

		private bool InitializeDSFieldGroups()
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT f.ID, f.Name AS FieldName, f.SubGroupID, sg.Name AS SubGroupName, " +
				" g.ID AS GroupID, g.Name AS GroupName " +
				" FROM Qa2Fields AS f INNER JOIN " +
				" Qa2SubGroups AS sg ON sg.ID = f.SubGroupID INNER JOIN " +
				" Qa2Groups AS g ON g.ID = sg.GroupID WHERE f.[Active]=1 " +
				" ORDER BY g.ID, f.SubGroupID, f.ID;" +
				" SELECT * FROM Qa2Groups;" +
				" SELECT * FROM Qa2SubGroups";

			//SqlConnection conn = LoginForm.GetSqlConnection();

			try
			{
				_dsFieldGroups = DataAccess.GetDataSet(sql);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not InitializeCheckFieldsTable()");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "InitializeCheckFieldsTable", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}
		#endregion initialize

		#region generic click and select
		public override void GenericClick(Control sender)
		{
			if (sender.Name == "btnVisit")
				SelectVisit();
			if (sender.Name == "btnPrint")
				Print();
		}

		public override bool Remove()
		{
			string message = "";
			StringBuilder sb = new StringBuilder();
			sb.Append("Press 'Yes' to confirm the removal of QA ID: " + this._currentPrimaryID.ToString());
			sb.Append(Environment.NewLine);
			sb.Append("or press 'No' to cancel.");
			if (MessageBox.Show(this._form, sb.ToString(), "Confirm QA Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
				return false;
			sb.Remove(0, sb.Length);

			//Qa2OtherData            
			Database db = DatabaseFactory.CreateDatabase();
			using (DbConnection conn = db.CreateConnection())
			{
				try
				{
					conn.Open();
					DbTransaction trans = conn.BeginTransaction();
					if (!RemoveFieldData(out message, db, trans))
					{
						trans.Rollback();
						sb.Append("Could not remove field data.");
						sb.Append(Environment.NewLine);
						sb.Append("Error: " + message);
						MessageBox.Show(this._form, sb.ToString(), "Remove Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}
					if (!RemoveOtherData(out message, db, trans))
					{
						trans.Rollback();
						sb.Append("Could not remove field data.");
						sb.Append(Environment.NewLine);
						sb.Append("Error: " + message);
						MessageBox.Show(this._form, sb.ToString(), "Remove Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}
					if (!RemoveQAData(out message, db, trans))
					{
						trans.Rollback();
						sb.Append("Could not remove field data.");
						sb.Append(Environment.NewLine);
						sb.Append("Error: " + message);
						MessageBox.Show(this._form, sb.ToString(), "Remove Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}
					trans.Commit();
					MessageBox.Show("QA ID:" + this._currentPrimaryID + " was removed.", "Remove Confirmation",
						MessageBoxButtons.OK, MessageBoxIcon.Information);

					return true;
				}
				catch (Exception ex)
				{
					//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
					sb.Append("Could not remove QA ID:" + this._currentPrimaryID + ".");
					sb.Append(Environment.NewLine);
					sb.Append("Error message: " + ex.Message);
					MessageBox.Show(this._form, sb.ToString(), "Remove Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return false;
				}
			}
		}

		protected bool RemoveFieldData(out string message, Database db, DbTransaction trans)
		{
			message = "";

			string sql = "DELETE FROM QA2FieldData WHERE QaID=" + this._currentPrimaryID;

			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sql);
				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		protected bool RemoveOtherData(out string message, Database db, DbTransaction trans)
		{
			message = "";

			string sql = "DELETE FROM QA2OtherData WHERE QaID=" + this._currentPrimaryID;

			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sql);
				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		protected bool RemoveQAData(out string message, Database db, DbTransaction trans)
		{
			message = "";

			string sql = "DELETE FROM QA2 WHERE ID=" + this._currentPrimaryID;

			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sql);
				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		private void Print()
		{
			string url = Properties.Settings.Default.Crema2_ReportingServices_ReportingService.ToString().Trim();
			string server = GetServerFromUrl(url);
			StringBuilder sb = new StringBuilder("http://" + server + "/reportserver?");
			//sb.Append("%2fGCRCAdmin%2fQaFormByQaID&rs:Command=Render&ID=" + this.CurrentPrimaryID);
			sb.Append("/GCRC/GCRCAdmin/QaFormByQaID&rs:Command=Render&ID=" + this.CurrentPrimaryID);

			System.Diagnostics.Process.Start(sb.ToString());
		}

		private string GetServerFromUrl(string url)
		{
			int pos1 = url.IndexOf("//");
			int pos2 = url.IndexOf("/", pos1 + 2);

			string retVal = url.Substring(pos1 + 2, (pos2 - pos1) - 2);
			return retVal;
		}

		private void SelectVisit()
		{
			StringBuilder sb = new StringBuilder();

			if (this._visitDate.IsNullDate)
			{
				sb.Append("You must first select a visit date");
				MessageBox.Show(this._form, sb.ToString(), "Select Visit Date", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				this._visitDate.Focus();
				return;
			}

			if (this._visitType.SelectedIndex == -1)
			{
				sb.Append("You must first select a visit type");
				MessageBox.Show(this._form, sb.ToString(), "Select Visit Type", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				this._visitType.Focus();
				return;
			}

			int visitType = (int)this._visitType.SelectedValue;
			Cursor.Current = Cursors.WaitCursor;
			SearchInfo si;
			if (visitType == 1)
				si = (SearchInfo)this._formInfo.SearchFormInfo["VisitOutPatient"];
			else
				si = (SearchInfo)this._formInfo.SearchFormInfo["VisitAdmission"];
			try
			{
				FormAncillaryAdmissionVisitSearch fs = new FormAncillaryAdmissionVisitSearch(si, this._visitDate.Value);
				fs.Text = "Visit Search";
				fs.ShowDialog(this._form);
				if (fs.DialogResult == DialogResult.OK)
				{
					VisitInfo vi = fs.SelectedVisitInfo;
					if (vi != null)
					{
						this._visitID.Text = vi.ID.ToString();
						this._fcManager.BusinessLogic.Central_Validating(_visitID, new CancelEventArgs());
						this._visitDate.Value = vi.VisitDate;
						this._fcManager.BusinessLogic.Central_Validating(_visitDate, new CancelEventArgs());
						GetPatientData(vi.PatientID);
						GetProtocolData(vi.ProtocolID);
					}
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not display outPatient visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void GetPatientData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT ID, MRN, LastName + ', ' + FirstName AS Name FROM Patient WHERE ID = " + id;

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (reader.Read())
				{
					this._patient.Text = reader.GetInt32(0).ToString();
					this._mrn.Text = reader.GetString(1);
					string name = "";
					if (!reader.IsDBNull(2))
						name = reader.GetString(2);
					this._patientName.Text = name;
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve patient!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Patient Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private void GetProtocolData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT p.ID, p.ProtocolNumber, " +
				" i.LastName + ', ' + i.FirstName AS Name " +
				" FROM Protocol p, ProtocolStaff ps, Investigator i " +
				" WHERE p.ID = " + id +
				" AND ps.ProtocolID = p.ID " +
				" AND ps.StaffTypeID = 1 " +
				" AND i.ID = ps.InvestigatorID";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (reader.Read())
				{
					this._protocol.Text = reader.GetInt32(0).ToString();
					//this._spid.Text = reader.GetInt32(1).ToString();
					this._protocolNumber.Text = reader.GetString(2);
					this._investigator.Text = reader.GetString(3);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve protocol information!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Protocol Information Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();				
			}
		}
		#endregion generic click and select

		#region new
		public override void New()
		{
			StringBuilder sb = new StringBuilder();
			//this assures us of an empty table
			string sql = "SELECT * FROM Qa2 WHERE 1=2;" +
				"SELECT * FROM QA2FieldData WHERE 1=2;" +
				"SELECT * FROM QA2OtherData WHERE 1=2";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_fcManager.DbTable = ds.Tables[0];

				DataRow dr = _fcManager.DbTable.NewRow();
				_fcManager.DbTable.Rows.Add(dr);
				_fcManager.CurrentRow = _fcManager.DbTable.Rows[0];

				//SetGridsNew();

				//for checkboxes                
				_dtCheckData = ds.Tables[1];
				_dtOtherData = ds.Tables[2];
				InitializeNewCheckDataTable();

				this._formMode = Shared.EditMode.Load;
				this._currentPrimaryID = -1;
				DisplayData();
				//GetCarryData();
				//GetDefaultData();

				//other text data

				SetFormMode(EditMode.New);
				SetIvControlsEnabled(false);
				_btnPrint.Enabled = false;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not create new table.");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "New Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}

		}

		private bool InitializeNewCheckDataTable()
		{
			StringBuilder sb = new StringBuilder();
			try
			{
				//use the CheckFields table to get a list of all the checkbox fields
				DataTable dt = _dsFieldGroups.Tables[0];
				foreach (DataRow dr in dt.Rows)
				{
					int fieldID = (int)dr["ID"];
					//create a new data row for the field
					DataRow drCkData = _dtCheckData.NewRow();
					drCkData["FieldID"] = fieldID;
					drCkData["Data"] = 0; //initialize to false;

					//get the associated row context
					RowContextCB rc = (RowContextCB)this._htrcCbItems[fieldID];
					rc._drData = drCkData;
					_dtCheckData.Rows.Add(drCkData);

					string fieldName = dr["FieldName"].ToString();
					if (fieldName == "Other")
					{
						//create a new row
						DataRow drOther = _dtOtherData.NewRow();
						drOther["FieldID"] = fieldID;
						drOther["Text"] = "";
						_dtOtherData.Rows.Add(drOther);

						//get the associated row context for the text box
						RowContextTB rct = (RowContextTB)this._htrcTbItems[fieldID];
						rct._drData = drOther;
					}
				}
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not InitializeCheckFieldsTable()");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "InitializeCheckFieldsTable", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}
		#endregion new

		#region save
		protected override bool CheckDuplicate()
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT COUNT(ID) FROM Qa2 WHERE VisitID=" + _visitID.Text +
				" AND VisitType=" + _visitType.SelectedValue.ToString();
			try
			{
				int i = (int)DataAccess.GetScalarObject(CommandType.Text, sql);
				if (i > 0)
				{
					sb.Append("There is another qa record with the same visit.");
					sb.Append(Environment.NewLine);
					sb.Append("Can't save duplicate qa.");
					MessageBox.Show(this._form, sb.ToString(), "Duplicate QA", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				sb.Append("Could not check for duplicates!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Check Duplicates Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return true;
			}
		}

		public override bool Save()
		{
			StringBuilder sb = new StringBuilder();
			string message = "";

			if (this._doSummaryValidate)
			{
				if (!VerifyAll())
					return false;
			}

			Console.WriteLine("RowState brfore save: " + this._fcManager.CurrentRow.RowState.ToString());
			Database db = DatabaseFactory.CreateDatabase();
			using (DbConnection conn = db.CreateConnection())
			{
				try
				{
					conn.Open();
					DbTransaction trans = conn.BeginTransaction();
					if (_formMode == EditMode.New)
					{
						if (CheckDuplicate())
							return false;
						if (CheckWarning())
							return false;
						//tableChange = DbTableChange.Insert;
						if (!SaveNew(out message, db, trans))
						{
							trans.Rollback();
							sb.Append("New record for " + this._formInfo.Name + " could not be saved.");
							sb.Append(Environment.NewLine);
							sb.Append("Error: " + message);
							MessageBox.Show(this._form, sb.ToString(), "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
							return false;
						}
					}
					else if (_formMode == EditMode.Edit)
					{
						if (!Update(out message, db, trans))
						{
							trans.Rollback();
							sb.Append("Update for " + this._formInfo.Name + " could not be saved.");
							sb.Append(Environment.NewLine);
							sb.Append("Error: " + message);
							MessageBox.Show(this._form, sb.ToString(), "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
							return false;
						}
					}

					if (!SaveCheckData(out message, db, trans))
					{
						trans.Rollback();
						sb.Append("Check data record for " + this._formInfo.Name + " could not be saved.");
						sb.Append(Environment.NewLine);
						sb.Append("Error: " + message);
						MessageBox.Show(this._form, sb.ToString(), "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}

					if (!SaveOtherData(out message, db, trans))
					{
						trans.Rollback();
						sb.Append("Other data record for " + this._formInfo.Name + " could not be saved.");
						sb.Append(Environment.NewLine);
						sb.Append("Error: " + message);
						MessageBox.Show(this._form, sb.ToString(), "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
						return false;
					}

					trans.Commit();
					ResetGrids();
					//confirmation dialog
					MessageBox.Show("Record was saved.", "Save Confirmation",
						MessageBoxButtons.OK, MessageBoxIcon.Information);

					bool shouldClose = (bool)this._configData["CloseOnSave"];

					if (shouldClose)
					{
						this._isClosing = true;
						this._form.Close();
					}
					else
					{
						this._fcManager.CurrentRow.AcceptChanges();
						this._dtCheckData.AcceptChanges();
						SetGridsAcceptChanges();
						SetFormMode(EditMode.Read);
					}
					this.FireTableChange(DbTableChange.Update);
					Console.WriteLine("RowState after save: " + this._fcManager.CurrentRow.RowState.ToString());


				}
				catch (Exception ex)
				{
					//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
					sb.Append("Form could not be saved.");
					sb.Append(Environment.NewLine);
					sb.Append("Error message: " + ex.Message);
					MessageBox.Show(this._form, sb.ToString(), "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
					return false;
				}
				finally
				{
					if (conn != null)
						conn.Dispose();
				}
				return true;
			}
		}

		private bool SaveCheckData(out string message, Database db, DbTransaction trans)
		{
			message = "";

			foreach (RowContextCB rc in this._alrcCbItems)
			{
				if (rc._drData.RowState == DataRowState.Added)
				{
					if (!SaveNewCheckDataRow(out message, db, trans, rc._drData))
						return false;
				}
				else
				{
					if (!UpdateCheckDataRow(out message, db, trans, rc._drData))
						return false;
				}
			}
			return true;
		}

		private bool SaveOtherData(out string message, Database db, DbTransaction trans)
		{
			message = "";

			foreach (RowContextTB rc in this._alrcTbItems)
			{
				if (rc._drData.RowState == DataRowState.Added)
				{
					if (!SaveNewOtherDataRow(out message, db, trans, rc._drData))
						return false;
					rc._drData.AcceptChanges();
				}
				else
				{
					if (!UpdateOtherDataRow(out message, db, trans, rc._drData))
						return false;
				}
			}
			return true;
		}

		private bool SaveNewCheckDataRow(out string message, Database db, DbTransaction trans, DataRow dr)
		{
			message = "";

			//sql insert
			string sqlIns = "INSERT INTO QA2FieldData (QaID,FieldID,Data) VALUES(@QaID,@FieldID,@Data)";

			SqlParameter[] aParams = new SqlParameter[3];
			aParams[0] = new SqlParameter("@QaID", SqlDbType.Int, 0, "QaID");
			aParams[0].Value = this.CurrentPrimaryID;
			aParams[1] = new SqlParameter("@FieldID", SqlDbType.Int, 0, "FieldID");
			aParams[1].Value = dr["FieldID"];
			aParams[2] = new SqlParameter("@Data", SqlDbType.Bit, 0, "Data");
			aParams[2].Value = dr["Data"];


			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlIns);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		private bool SaveNewOtherDataRow(out string message, Database db, DbTransaction trans, DataRow dr)
		{
			message = "";

			//sql insert
			string sqlIns = "INSERT INTO QA2OtherData (QaID,FieldID,Text) VALUES(@QaID,@FieldID,@Text)";

			SqlParameter[] aParams = new SqlParameter[3];
			aParams[0] = new SqlParameter("@QaID", SqlDbType.Int, 0, "QaID");
			aParams[0].Value = this.CurrentPrimaryID;
			aParams[1] = new SqlParameter("@FieldID", SqlDbType.Int, 0, "FieldID");
			aParams[1].Value = dr["FieldID"];
			aParams[2] = new SqlParameter("@Text", SqlDbType.Text, 500, "Text");
			aParams[2].Value = dr["Text"];


			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlIns);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		private bool UpdateCheckDataRow(out string message, Database db, DbTransaction trans, DataRow dr)
		{
			message = "";

			//sql 
			string sqlIns = "UPDATE QA2FieldData SET Data=@Data " +
				" WHERE QaID=@QaID AND FieldID= @FieldID";

			SqlParameter[] aParams = new SqlParameter[3];
			aParams[0] = new SqlParameter("@Data", SqlDbType.Bit, 0, "Data");
			aParams[0].Value = dr["Data"];
			aParams[1] = new SqlParameter("@QaID", SqlDbType.Int, 0, "QaID");
			aParams[1].Value = this.CurrentPrimaryID;
			aParams[2] = new SqlParameter("@FieldID", SqlDbType.Int, 0, "FieldID");
			aParams[2].Value = dr["FieldID"];


			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlIns);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		private bool UpdateOtherDataRow(out string message, Database db, DbTransaction trans, DataRow dr)
		{
			message = "";

			//sql 
			string sqlIns = "UPDATE QA2OtherData SET Text=@Text " +
				" WHERE QaID=@QaID AND FieldID= @FieldID";

			SqlParameter[] aParams = new SqlParameter[3];
			aParams[0] = new SqlParameter("@Text", SqlDbType.Text, 500, "Text");
			aParams[0].Value = dr["Text"];
			aParams[1] = new SqlParameter("@QaID", SqlDbType.Int, 0, "QaID");
			aParams[1].Value = this.CurrentPrimaryID;
			aParams[2] = new SqlParameter("@FieldID", SqlDbType.Int, 0, "FieldID");
			aParams[2].Value = dr["FieldID"];


			try
			{
				DbCommand cmd = db.GetSqlStringCommand(sqlIns);
				DataAccess.AddParamArrayToDbCommand(cmd, aParams);

				int i = db.ExecuteNonQuery(cmd, trans);
				return true;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = ex.Message;
				return false;
			}
		}

		protected virtual bool VerifyIvAudit(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;
			int val = int.Parse(ctl.Text);
			if (val == 0)
				return true;

			if (_sticks.Value < 1)
			{
				fc.ErrorMessage = "Stick Attempts must be greater than 0";
				return false;
			}
			if (_painScale.SelectedIndex < 1)
			{
				fc.ErrorMessage = "Pain Scale is reguired";
				return false;
			}
			if (_sampleCollection.SelectedIndex < 1)
			{
				fc.ErrorMessage = "Sample Collection is reguired";
				return false;
			}
			if (_piuNothing.Checked == false && _piuBehavioral.Checked == false && _piuOther.Checked == false && _piuPharmacologic.Checked == false && _piuNotDocumented.Checked == false)
			{
				fc.ErrorMessage = "Pain intervention used is reguired";
				return false;
			}
			if (_piuOther.Checked)
			{
				string s = _otherTechnique.Text.Trim();
				if (s.Length == 0)
				{
					fc.ErrorMessage = "Other pain intervention description is requird";
					return false;
				}
			}
			return true;
		}

		protected virtual bool VerifyNurse(Control ctl)
		{
			FieldContext fc = (FieldContext)ctl.Tag;
			ComboBox cb = (ComboBox)ctl;

			if (cb.SelectedIndex == -1)
			{
				fc.ErrorMessage = "Nruse is a required field";
				return false;
			}

			if ((int)cb.SelectedValue < 2)
			{
				fc.ErrorMessage = "Nurse is a required field";
				return false;
			}

			return true;
		}
		#endregion save

		#region display data
		public override void DisplayData()
		{
			DisplayDataBase();

			DisplayCheckData();
			DisplayOtherData();
			if (this._visitID.Text.Length > 0)
			{
				int visitID = Convert.ToInt32(this._visitID.Text);
				GetVisitPatientProtocolData(visitID);
			}
			else
				ClearNonFieldContextControls();

		}

		private void DisplayDataBase()
		{
			string fieldType;
			string controlType;
			string sVal;
			Control ctl;

			foreach (FieldContext fc in _fcManager.Items)
			{
				ctl = fc.Control;
				if (ctl == null)
					continue;

				fieldType = fc.Column.DataType.ToString();
				controlType = ctl.GetType().ToString();

				//disable controls while in read mode
				if (this._formMode == EditMode.Load)
					ctl.Enabled = false;
				else
					ctl.Enabled = true;

				_form.errP.SetError(ctl, "");

				switch (controlType)
				{
					case "System.Windows.Forms.MaskedTextBox":
						sVal = _fcManager.CurrentRow[fc.Column.ColumnName].ToString();
						ctl.Text = sVal;
						break;

					case "System.Windows.Forms.TextBox":
						//have to some thing here for numerics
						sVal = _fcManager.CurrentRow[fc.Column.ColumnName].ToString();
						ctl.Text = sVal;
						break;

					case "Syncfusion.Windows.Forms.Tools.DateTimePickerAdv":
						DateTimePickerAdv dtp = (DateTimePickerAdv)ctl;
						if (fc.Column.ColumnName == "IncidentTime")
						{
							dtp.Value = DateTime.Parse(_fcManager.CurrentRow[fc.Column.ColumnName].ToString());
						}
						else
						{
							if (_fcManager.CurrentRow[fc.Column.ColumnName] is System.DBNull)
							{
								dtp.Value = DateTime.Today;
								dtp.IsNullDate = true;
							}
							else
							{
								dtp.IsNullDate = false;
								dtp.Value = (DateTime)_fcManager.CurrentRow[fc.Column.ColumnName];
							}
						}
						break;

					case "System.Windows.Forms.CheckBox":
						CheckBox chk = (CheckBox)ctl;
						chk.Checked = false;
						if (_fcManager.CurrentRow[fc.Column.ColumnName] != System.DBNull.Value)
							chk.Checked = (bool)_fcManager.CurrentRow[fc.Column.ColumnName];
						break;

					case "System.Windows.Forms.ComboBox":
						ComboBox cbo = (ComboBox)ctl;
						if (_fcManager.CurrentRow[fc.Column.ColumnName] == System.DBNull.Value)
						{
							cbo.SelectedIndex = -1;
							cbo.SelectedIndex = -1;
						}
						else
							cbo.SelectedValue = (int)_fcManager.CurrentRow[fc.Column.ColumnName];
						break;

					case "Syncfusion.Windows.Forms.Tools.NumericUpDownExt":
						NumericUpDownExt nud = (NumericUpDownExt)ctl;
						if (_fcManager.CurrentRow[fc.Column.ColumnName] == System.DBNull.Value) //new
							nud.Value = 0;
						else
							nud.Value = (int)_fcManager.CurrentRow[fc.Column.ColumnName];
						break;
				}
				if (ctl.Name == "IncidentTime")
				{
					if (_incidentTime.Text.Length == 0) //new
						_incidentTime.Text = "00:00:00";
					_dtpIncidentTime.Value = DateTime.Parse(_incidentTime.Text);
				}
				if (ctl.Name == "IvAudit")
				{
					if (ctl.Text.Length == 0) //new
						ctl.Text = "0";
					switch (ctl.Text)
					{
						case "0":
							_rdoNone.Checked = true;
							break;
						case "1":
							_rdoIV.Checked = true;
							break;
						case "2":
							_rdoPhlebotomy.Checked = true;
							break;
					}
				}
			}
		}

		private void DisplayCheckData()
		{
			foreach (RowContextCB rc in this._alrcCbItems)
			{
				//disable controls while in read mode
				if (this._formMode == EditMode.Load)
					rc._control.Enabled = false;
				else
					rc._control.Enabled = true;

				rc._control.Checked = false;
				if (rc._drData["Data"] != System.DBNull.Value)
					rc._control.Checked = (bool)rc._drData["Data"];
			}
		}

		private void DisplayOtherData()
		{
			foreach (RowContextTB rc in this._alrcTbItems)
			{
				//disable controls while in read mode
				if (this._formMode == EditMode.Load)
					rc._control.Enabled = false;
				else
					rc._control.Enabled = true;

				if (rc._drData["Text"] != System.DBNull.Value)
					rc._control.Text = rc._drData["Text"].ToString();
			}
		}

		private void ClearNonFieldContextControls()
		{
			_visitDate.IsNullDate = true;
			_patient.Text = "";
			_mrn.Text = "";
			_patientName.Text = "";
			_protocol.Text = "";
			//_spid.Text = "";
			_protocolNumber.Text = "";
			_investigator.Text = "";
			_timeIn.Text = "";
		}

		private void ClearIvStickControls()
		{
			_sticks.Value = 0;
			_painScore.Value = 0;
			_recovery.Value = 0;
			_painScale.SelectedIndex = -1;
			_sampleCollection.SelectedIndex = -1;
			_piuBehavioral.Checked = false;
			_piuNothing.Checked = false;
			_piuOther.Checked = false;
			_piuPharmacologic.Checked = false;
			_otherTechnique.Text = "";

		}

		protected override void ResetToOriginal()
		{
			this._formMode = EditMode.Load;

			if (this._fcManager.CurrentRow.RowState == DataRowState.Added || this._fcManager.CurrentRow.RowState == DataRowState.Deleted)
			{
				this._fcManager.DbTable = null;
				this._fcManager.CurrentRow = null;
				this._dtCheckData = null;

				ClearAllControls();
				_form.pnl2.Enabled = false;
				SetFormMode(EditMode.Empty);
			}
			else
			{
				this._fcManager.CurrentRow.RejectChanges();
				foreach (RowContextCB rc in this._alrcCbItems)
				{
					rc._drData.RejectChanges();
				}

				DisplayData();
				SetFormMode(EditMode.Read);
			}
		}

		protected override void ClearAllControls()
		{
			base.ClearAllControls();
			ClearNonFieldContextControls();
			//ClearAllCheckData
			foreach (RowContextCB rc in this._alrcCbItems)
			{
				rc._control.Checked = false;
				rc._drData = null;
			}
		}

		private void GetVisitPatientProtocolData(int id)
		{
			string visitTable = "";
			int patientID = -1;
			int protocolID = -1;

			if (this._visitType.SelectedIndex == -1)
				return;

			if ((int)this._visitType.SelectedValue == 1)
				visitTable = "ProtocolVisitOutPatient";
			else
				visitTable = "ProtocolVisitAdmission";

			StringBuilder sb = new StringBuilder();
			string sql = "SELECT Patient,Protocol,TimeIn " +
				" FROM " + visitTable +
				" WHERE ID = " + id;


			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);
				if (reader.Read())
				{
					patientID = reader.GetInt32(0);
					protocolID = reader.GetInt32(1);
					if (!reader.IsDBNull(2))
						_timeIn.Text = reader.GetString(2) + "m";
					else
						_timeIn.Text = "";
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve visit info!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Visit Info Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
				if (patientID > 0)
					this.GetPatientData(patientID);
				if (protocolID > 0)
					this.GetProtocolData(protocolID);
			}
		}

		protected override void SetControlsEnabled(bool enable)
		{
			base.SetControlsEnabled(enable);
			_patient.Enabled = enable;
			_mrn.Enabled = enable;
			_patientName.Enabled = enable;
			_btnVisit.Enabled = enable;
			_btnPrint.Enabled = enable;
			_protocol.Enabled = enable;
			//_spid.Enabled = enable;
			_protocolNumber.Enabled = enable;
			_investigator.Enabled = enable;
			_rdoPhlebotomy.Enabled = enable;
			_rdoNone.Enabled = enable;
			_rdoIV.Enabled = enable;
			_dtpIncidentTime.Enabled = enable;
			_timeIn.Enabled = enable;

			if (enable)
			{
				if (_rdoNone.Checked)
					SetIvControlsEnabled(false);
				if (!_piuOther.Checked)
					_otherTechnique.Enabled = false;
			}

			foreach (RowContextCB rc in this._alrcCbItems)
			{
				rc._control.Enabled = enable;
			}
			foreach (RowContextTB rc in this._alrcTbItems)
			{
				rc._control.Enabled = enable;
			}

		}
		#endregion display data

		#region get data
		public override bool GetData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT * FROM Qa2 " +
				" WHERE ID=" + id;

			//SqlConnection conn = LoginForm.GetSqlConnection();			
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				DataTable dt = ds.Tables[0];
				if (dt.Rows.Count == 1)
				{
					_fcManager.DbTable = dt;
					_fcManager.CurrentRow = dt.Rows[0];
					this._formMode = Shared.EditMode.Load;
					this._currentPrimaryID = id;

					GetCheckData();
					GetOtherData();
					DisplayData();
					//GetGridData(id);
				}
				//this.CarryNewClicked(this._chkCarry);                

				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Error in retrieving data");
				sb.Append(Environment.NewLine);
				sb.Append(ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Get Data Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				this.ClearCarryData();
				return false;
			}
		}

		private void GetOtherData()
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT * FROM QA2OtherData" +
				" WHERE QaID=" + this.CurrentPrimaryID.ToString();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_dtOtherData = ds.Tables[0];

				if (_htNewOtherItems.Count > 0)
				{
					//add any new 'other' fields
					foreach (DictionaryEntry de in _htNewOtherItems)
					{
						RowContextTB rct = (RowContextTB)de.Value;

						DataRow drn = this._dtOtherData.NewRow();
						drn["FieldID"] = (int)de.Key;
						drn["QaID"] = this.CurrentPrimaryID;
						drn["Text"] = "";
						this._dtOtherData.Rows.Add(drn);
					}
				}

				//iterate through each row and assign row to row context
				foreach (DataRow dr in _dtOtherData.Rows)
				{
					int fieldID = (int)dr["FieldID"];

					//get the associated row context					
					RowContextTB rc = (RowContextTB)this._htrcTbItems[fieldID];
					rc._drData = dr;
				}
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not get other data()");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "GetOtherData", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void GetCheckData()
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT * FROM QA2FieldData" +
				" WHERE QaID=" + this.CurrentPrimaryID.ToString();
			try
			{
				DataSet ds = DataAccess.GetDataSet(sql);
				_dtCheckData = ds.Tables[0];

				//this could be a newly added field - the field might not
				//be included in the _dtCheckData data table 
				//so we must add a new data row if there is one

				//need a primary key to search for exisiting contextRow
				_dtCheckData.PrimaryKey = new DataColumn[] { _dtCheckData.Columns["FieldID"] };
				CheckForNewFields();

				//iterate through each row and assign row to row context
				foreach (DataRow dr in _dtCheckData.Rows)
				{
					int fieldID = (int)dr["FieldID"];

					//get the associated row context
					//data for this field might be inactive so check first
					if (_htrcCbItems.Contains(fieldID))
					{
						RowContextCB rc = (RowContextCB)this._htrcCbItems[fieldID];
						rc._drData = dr;
					}
				}
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not get check data");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "InitializeCheckFieldsTable", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void CheckForNewFields()
		{
			ArrayList alNew = new ArrayList();
			_htNewOtherItems = new Hashtable();

			int fieldID;
			DataRow drFound = null;

			foreach (RowContextCB rc in this._alrcCbItems)
			{
				fieldID = (int)rc._drField["ID"];
				drFound = _dtCheckData.Rows.Find(fieldID);

				if (drFound == null)
				{
					DataRow drn = this._dtCheckData.NewRow();
					drn["FieldID"] = fieldID;
					drn["QaID"] = this.CurrentPrimaryID;
					drn["Data"] = 0;
					this._dtCheckData.Rows.Add(drn);
					rc._drData = drn;

					//new Other checkbox - must add this to other data table
					if (rc._control.Text == "Other")
					{
						RowContextTB rct = (RowContextTB)_htrcTbItems[fieldID];
						_htNewOtherItems.Add(fieldID, rct);
					}
				}
			}
		}
		#endregion get data

		#region internal
		internal class RowContextCB
		{
			internal RowContextCB()
			{
			}

			internal CheckBox _control = null;
			internal DataRow _drField = null; //holds the field id, name and group
			internal DataRow _drData = null;

			internal bool CurrentValue()
			{
				return _control.Checked;
			}

		}

		internal class RowContextTB
		{
			internal RowContextTB()
			{
			}

			internal TextBox _control = null;
			internal int _fieldID = 0;
			internal DataRow _drData = null;

			internal string CurrentValue()
			{
				return _control.Text;
			}

		}
		#endregion internal

		#region search get and display
		public override void Search(object sender)
		{
			Control ctl = (Control)sender;
			ctl.Enabled = false;

			SelectQADialog sad = new SelectQADialog();
			sad.Text = this._formInfo.Name + " Search";
			sad.ShowDialog(this._formMain);
			switch (sad.SearchChoice)
			{
				case -1:
					break;
				case 0:
					SelectByStandard();
					break;
				case 1:
					SelectByOutpatientVisits();
					break;
				case 2:
					SelectByAdmissions();
					break;
				case 3:
					SelectByPatient();
					break;
				case 4:
					SelectByProtocol();
					break;
				case 5:
					SelectByInvestigator();
					break;
			}


			ctl.Enabled = true;

		}

		private void SelectByInvestigator()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Investigator"];
			_searchType = SearchTypes.Investigator;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void SelectByProtocol()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Protocol"];
			_searchType = SearchTypes.Protocol;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByPatient()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Patient"];
			_searchType = SearchTypes.Patient;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display patient seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByOutpatientVisits()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["OutPatientVisit"];
			_searchType = SearchTypes.OutpatientVisits;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display outpatient visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByAdmissions()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["AdmissionVisit"];
			_searchType = SearchTypes.Admissions;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display Outpatient Visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByStandard()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Qa2"];

			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Owner = this._form;
				fs.Controller.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(sc_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display out patient visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private int SelectFromResults(int id, string recordType, string searchBy, string searchResultKey)
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchResultInfo si = (SearchResultInfo)this._formInfo.SearchResultInfo[searchResultKey];
			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				//first see if there are any visits for this patient
				string sql = si.SqlCommand;
				if (sql.IndexOf("@@") > 0)
					sql = sql.Replace("@@", id.ToString());
				else
					sql += id;

				DataSet ds = DataAccess.GetDataSet(sql);
				DataTable dt = ds.Tables[0];
				if (dt.Rows.Count == 0)
				{
					MessageBox.Show("There are no " + recordType + " for " + searchBy + " id: " + id, "No " + recordType + " Found", MessageBoxButtons.OK, MessageBoxIcon.Information);
					return 0;
				}
				SearchUtils.SetColumnMeta(dt, si);
				FormSearchResultsBase fsr = (FormSearchResultsBase)SearchUtils.GetSearchResultsDialog(si, dt);
				fsr.Text = searchBy + " Search";
				fsr.Controller.BusinessLogic.ItemSelected += new BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(BusinessLogic_ItemSelected);
				fsr.Closing += new CancelEventHandler(fsr_Closing);
				fsr.Owner = this._form;
				fsr.Show();
				return 1;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not retrieve select results.");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "Select Results Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return 0;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private void scr_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			string recordType = "";
			string searchBy = "";
			string searchResultsKey = "";

			switch (this._searchType)
			{
				case SearchTypes.Admissions:
					recordType = "QA records";
					searchBy = "Admission Visit";
					searchResultsKey = "AdmissionQA";
					break;
				case SearchTypes.OutpatientVisits:
					recordType = "QA records";
					searchBy = "Out Patient Visit";
					searchResultsKey = "OutpatientQA";
					break;
				case SearchTypes.Investigator:
					recordType = "QA records";
					searchBy = "Protocol";
					searchResultsKey = "ProtocolQA";
					break;
				case SearchTypes.Patient:
					recordType = "QA records";
					searchBy = "Patient";
					searchResultsKey = "PatientQA";
					break;
				case SearchTypes.Protocol:
					recordType = "QA records";
					searchBy = "Protocol";
					searchResultsKey = "ProtocolQA";
					break;
			}
			if (e.ID > 0)
				SelectFromResults(e.ID, recordType, searchBy, searchResultsKey);
		}

		private void BusinessLogic_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			if (e.ID > 0)
			{
				if (this.GetData(e.ID))
				{
					if (this.FormMode == EditMode.Load)
						SetFormMode(EditMode.Read);
				}
			}
		}

		private void fsr_Closing(object sender, CancelEventArgs e)
		{

		}

		private void sc_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			if (e.ID > 0)
			{
				Console.WriteLine("Selected ID: " + e.ID.ToString());
				if (GetData(e.ID))
				{
					if (this.FormMode == EditMode.Load)
						SetFormMode(EditMode.Read);
				}
			}
			else
				Console.WriteLine("ID: " + e.ID);
		}

		private void fs_Closing(object sender, CancelEventArgs e)
		{
			IsSearchVisible = false;
			this._form.btnSearch.Enabled = true;
		}
		#endregion search get and display
	}
}
